package com.dmp.util;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.Pipeline;
import redis.clients.jedis.exceptions.JedisException;

import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

/**
 * Jedis 书写类JedisWriteUtils 说明：这里JedisWriteUtils和JedisReadUtils的方法是一一对应的
 */
public class JedisWriteUtils {
    private static Logger logger = LoggerFactory.getLogger(JedisWriteUtils.class);
    private static JedisPool pool;
    private static Pipeline pipe = null;
    private static Jedis jedisPipe = null;
    private static int sysnCurPipe = 0;
    private static int sysnMaxPipe = 5000;

    /**
     * 从文件名获取参数，配置redis连接
     *
     * @param fileName
     */
    public static void setJedisPool(String fileName) {
        if (fileName == null) {
            fileName = "default.properties";
        }

        Properties props = new Properties();
        try {
            props.load(JedisReadUtils.class.getClassLoader().getResourceAsStream(fileName));
        } catch (IOException e) {
            logger.error(e.getMessage());
            throw (new JedisException("can not load from file:" + fileName));
        }

        String host = props.getProperty("redis.host");
        int port = Integer.parseInt(props.getProperty("redis.port"));
        int timeout = Integer.parseInt(props.getProperty("redis.timeout"));
        String sysnMaxPipeStr = props.getProperty("redis.sysnMaxPipe");
        String password = props.getProperty("redis.password");
        if (null != sysnMaxPipeStr) {
            sysnMaxPipe = Integer.parseInt(sysnMaxPipeStr);
        }

        JedisPoolConfig config = new JedisPoolConfig();
        config.setMaxTotal(100);
        config.setMaxIdle(20);
        config.setMaxWaitMillis(1000l);
        config.setTestOnBorrow(false);

        // 线程数量限制，IP地址，端口，超时时间
        if (StrUtils.isNotBlank(password)) {
            //采用有密码登录
            pool = new JedisPool(config, host, port, timeout, password);
        } else {
            pool = new JedisPool(config, host, port, timeout);
        }
    }

    /**
     * 设置redis连接JedisPool
     *
     * @param jedisPool
     */
    public static void setJedisPool(JedisPool jedisPool) {
        if (null == jedisPool) {
            throw (new JedisException("param's jedisPool is null."));
        }

        JedisWriteUtils.pool = jedisPool;
    }

    /**
     * @param key
     * @param field
     * @param increment
     * @return void
     * @author sunzy
     * @date 2016年3月4日 下午5:25:36
     * @Description 为key中的域 field 的值加上增量 increment
     */
    public static Long hincrBy(String key, String field, long increment) {
        Jedis jedis = null;
        Long value = null;
        boolean isBroken = false;
        try {
            jedis = getJedis();

            value = jedis.hincrBy(key.getBytes(), field.getBytes(), increment);
        } catch (Exception e) {
            isBroken = true;
            e.printStackTrace();
        } finally {
            if (jedis != null)
                release(jedis, isBroken);
        }

        return value;
    }

    /**
     * 设置缓存
     *
     * @param key          键
     * @param value        值
     * @param cacheSeconds 超时时间，0为不超时
     * @return
     */
    public static String set(String key, String value, int cacheSeconds) {
        String result = null;
        Jedis jedis = null;
        boolean isBroken = false;
        try {
            jedis = getJedis();
            result = jedis.set(key, value);
            if (cacheSeconds != 0) {
                jedis.expire(key, cacheSeconds);
            }
            logger.debug("set {} = {}", key, value);
        } catch (Exception e) {
            isBroken = true;
            logger.warn("set {} = {}", key, value, e);
        } finally {
            release(jedis, isBroken);
        }
        return result;
    }

    /**
     * 设置缓存
     *
     * @param key          键
     * @param value        值
     * @param cacheSeconds 超时时间，0为不超时
     * @return
     */
    public static String setObject(String key, Object value, int cacheSeconds) {
        String result = null;
        Jedis jedis = null;
        boolean isBroken = false;
        try {
            jedis = getJedis();
            result = jedis.set(getBytesKey(key), toBytes(value));
            if (cacheSeconds != 0) {
                jedis.expire(key, cacheSeconds);
            }
            logger.debug("setObject {} = {}", key, value);
        } catch (Exception e) {
            isBroken = true;
            logger.warn("setObject {} = {}", key, value, e);
        } finally {
            release(jedis, isBroken);
        }
        return result;
    }

    /**
     * 设置List缓存
     *
     * @param key          键
     * @param value        值
     * @param cacheSeconds 超时时间，0为不超时
     * @return
     */
    public static long setList(String key, List<String> value, int cacheSeconds) {
        long result = 0;
        Jedis jedis = null;
        boolean isBroken = false;
        try {
            jedis = getJedis();
            if (jedis.exists(key)) {
                jedis.del(key);
            }
            result = jedis.rpush(key, (String[]) value.toArray());
            if (cacheSeconds != 0) {
                jedis.expire(key, cacheSeconds);
            }
            logger.debug("setList {} = {}", key, value);
        } catch (Exception e) {
            isBroken = true;
            logger.warn("setList {} = {}", key, value, e);
        } finally {
            release(jedis, isBroken);
        }
        return result;
    }

    /**
     * 设置List缓存
     *
     * @param key          键
     * @param value        值
     * @param cacheSeconds 超时时间，0为不超时
     * @return
     */
    public static long setObjectList(String key, List<Object> value,
                                     int cacheSeconds) {
        long result = 0;
        Jedis jedis = null;
        boolean isBroken = false;
        try {
            jedis = getJedis();
            if (jedis.exists(getBytesKey(key))) {
                jedis.del(key);
            }
            List<byte[]> list = Lists.newArrayList();
            for (Object o : value) {
                list.add(toBytes(o));
            }
            result = jedis.rpush(getBytesKey(key), (byte[][]) list.toArray());
            if (cacheSeconds != 0) {
                jedis.expire(key, cacheSeconds);
            }
            logger.debug("setObjectList {} = {}", key, value);
        } catch (Exception e) {
            isBroken = true;
            logger.warn("setObjectList {} = {}", key, value, e);
        } finally {
            release(jedis, isBroken);
        }
        return result;
    }

    /**
     * 向List缓存中添加值
     *
     * @param key   键
     * @param value 值
     * @return
     */
    public static long listAdd(String key, String... value) {
        long result = 0;
        Jedis jedis = null;
        boolean isBroken = false;
        try {
            jedis = getJedis();
            result = jedis.rpush(key, value);
            logger.debug("listAdd {} = {}", key, value);
        } catch (Exception e) {
            isBroken = true;
            logger.warn("listAdd {} = {}", key, value, e);
        } finally {
            release(jedis, isBroken);
        }
        return result;
    }

    /**
     * 向List缓存中添加值
     *
     * @param key   键
     * @param value 值
     * @return
     */
    public static long listObjectAdd(String key, Object... value) {
        long result = 0;
        Jedis jedis = null;
        boolean isBroken = false;
        try {
            jedis = getJedis();
            List<byte[]> list = Lists.newArrayList();
            for (Object o : value) {
                list.add(toBytes(o));
            }
            result = jedis.rpush(getBytesKey(key), (byte[][]) list.toArray());
            logger.debug("listObjectAdd {} = {}", key, value);
        } catch (Exception e) {
            isBroken = true;
            logger.warn("listObjectAdd {} = {}", key, value, e);
        } finally {
            release(jedis, isBroken);
        }
        return result;
    }

    /**
     * 设置Set缓存
     *
     * @param key          键
     * @param value        值
     * @param cacheSeconds 超时时间，0为不超时
     * @return
     */
    public static long setSet(String key, Set<String> value, int cacheSeconds) {
        long result = 0;
        Jedis jedis = null;
        boolean isBroken = false;
        try {
            jedis = getJedis();
            if (jedis.exists(key)) {
                jedis.del(key);
            }
            result = jedis.sadd(key, (String[]) value.toArray());
            if (cacheSeconds != 0) {
                jedis.expire(key, cacheSeconds);
            }
            logger.debug("setSet {} = {}", key, value);
        } catch (Exception e) {
            isBroken = true;
            logger.warn("setSet {} = {}", key, value, e);
        } finally {
            release(jedis, isBroken);
        }
        return result;
    }

    /**
     * 设置Set缓存
     *
     * @param key          键
     * @param value        值
     * @param cacheSeconds 超时时间，0为不超时
     * @return
     */
    public static long setObjectSet(String key, Set<Object> value, int cacheSeconds) {
        long result = 0;
        Jedis jedis = null;
        boolean isBroken = false;
        try {
            jedis = getJedis();
            if (jedis.exists(getBytesKey(key))) {
                jedis.del(key);
            }
            Set<byte[]> set = Sets.newHashSet();
            for (Object o : value) {
                set.add(toBytes(o));
            }
            result = jedis.sadd(getBytesKey(key), (byte[][]) set.toArray());
            if (cacheSeconds != 0) {
                jedis.expire(key, cacheSeconds);
            }
            logger.debug("setObjectSet {} = {}", key, value);
        } catch (Exception e) {
            isBroken = true;
            logger.warn("setObjectSet {} = {}", key, value, e);
        } finally {
            release(jedis, isBroken);
        }
        return result;
    }

    /**
     * 向Set缓存中添加值
     *
     * @param key   键
     * @param value 值
     * @return
     */
    public static long setSetAdd(String key, String... value) {
        long result = 0;
        Jedis jedis = null;
        boolean isBroken = false;
        try {
            jedis = getJedis();
            result = jedis.sadd(key, value);
            logger.debug("setSetAdd {} = {}", key, value);
        } catch (Exception e) {
            isBroken = true;
            logger.warn("setSetAdd {} = {}", key, value, e);
        } finally {
            release(jedis, isBroken);
        }
        return result;
    }

    /**
     * 向Set缓存中添加值
     *
     * @param key   键
     * @param value 值
     * @return
     */
    public static long setSetObjectAdd(String key, Object... value) {
        long result = 0;
        Jedis jedis = null;
        boolean isBroken = false;
        try {
            jedis = getJedis();
            Set<byte[]> set = Sets.newHashSet();
            for (Object o : value) {
                set.add(toBytes(o));
            }
            result = jedis.rpush(getBytesKey(key), (byte[][]) set.toArray());
            logger.debug("setSetObjectAdd {} = {}", key, value);
        } catch (Exception e) {
            isBroken = true;
            logger.warn("setSetObjectAdd {} = {}", key, value, e);
        } finally {
            release(jedis, isBroken);
        }
        return result;
    }

    /**
     * 设置HashMap缓存
     *
     * @param key
     * @param field
     * @param obj
     */
    public static void setHashMap(String key, String field, Object obj) {
        setHashMap(key, field, obj, 0);
    }

    /**
     * 设置HashMap缓存
     *
     * @param key
     * @param field
     * @param value
     */
    public static void setHashMap(String key, String field, String value) {
        setHashMap(key, field, value, 0);
    }

    /**
     * 设置HashMap缓存
     *
     * @param key
     * @param field
     * @param obj
     * @param cacheSeconds 超时时间，0为不超时
     */
    public static void setHashMap(String key, String field, Object obj, int cacheSeconds) {
        Jedis jedis = null;
        boolean isBroken = false;
        try {
            jedis = getJedis();
            if (jedis.hexists(getBytesKey(key), getBytesKey(field))) {
                jedis.hdel(getBytesKey(key), getBytesKey(field));
            }
            jedis.hset(getBytesKey(key), getBytesKey(field), toBytes(obj));
            if (cacheSeconds != 0) {
                jedis.expire(key, cacheSeconds);
            }
        } catch (Exception e) {
            isBroken = true;
            logger.warn("setHashMap {} = {}", key, field, e);
        } finally {
            release(jedis, isBroken);
        }
    }

    /**
     * 设置HashMap缓存
     *
     * @param key
     * @param field
     * @param value
     * @param cacheSeconds 超时时间，0为不超时
     */
    public static void setHashMap(String key, String field, String value, int cacheSeconds) {
        Jedis jedis = null;
        boolean isBroken = false;
        try {
            jedis = getJedis();
            if (jedis.hexists(getBytesKey(key), getBytesKey(field))) {
                jedis.hdel(getBytesKey(key), getBytesKey(field));
            }
            jedis.hset(key, field, value);
            if (cacheSeconds != 0) {
                jedis.expire(key, cacheSeconds);
            }
        } catch (Exception e) {
            isBroken = true;
            logger.warn("setHashMap {} = {}", key, field, e);
        } finally {
            release(jedis, isBroken);
        }
    }



    /**
     * @param key
     * @param seconds
     * @return void
     * @Description 设置失效时间
     * @author suzzy
     * @date 2016年7月22日 上午11:41:29
     */
    public static void setExpire(String key, int seconds) {
        Jedis jedis = null;
        boolean isBroken = false;
        try {
            jedis = getJedis();
            jedis.expire(key, seconds);
        } catch (Exception e) {
            isBroken = true;
            logger.warn("setExpire {} ", key, e);
        } finally {
            release(jedis, isBroken);
        }
    }

    /**
     * @param key
     * @param field
     * @param value
     * @param seconds
     * @return void
     * @Description 设置HashMap缓存，并设置失效时间
     * @author suzzy
     * @date 2016年7月22日 上午11:42:02
     */
    public static void setHashMapExpire(String key, String field, String value, int seconds) {
        Jedis jedis = null;
        boolean isBroken = false;
        try {
            jedis = getJedis();
            if (jedis.hexists(getBytesKey(key), getBytesKey(field))) {
                jedis.hdel(getBytesKey(key), getBytesKey(field));
            }
            jedis.hset(key, field, value);
            jedis.expire(key, seconds);
        } catch (Exception e) {
            isBroken = true;
            logger.warn("setHashMap {} = {}", key, field, e);
        } finally {
            release(jedis, isBroken);
        }
    }

    /**
     * @param key
     * @param field
     * @param value
     * @return void
     * @Description 设置HashMap缓存，并设置失效时间
     * @author suzzy
     * @date 2016年7月22日 上午11:42:17
     */
    public static void setHashMapExpire(String key, String field, String value) {
        setHashMapExpire(key, field, value, 3600 * 24 * 7);
    }

    /**
     * 设置HashMap缓存
     *
     * @param key
     * @param field
     * @param obj
     */
    public static void setHashMapString(String key, String field, String value) {
        Jedis jedis = null;
        boolean isBroken = false;
        try {
            jedis = getJedis();
            if (jedis.hexists(getBytesKey(key), getBytesKey(field))) {
                jedis.hdel(getBytesKey(key), getBytesKey(field));
            }
            jedis.hset(key, field, value);
        } catch (Exception e) {
            isBroken = true;
            logger.warn("setHashMap {} = {}", key, field, e);
        } finally {
            release(jedis, isBroken);
        }
    }

    /**
     * 设置Map缓存
     *
     * @param key          键
     * @param value        值
     * @param cacheSeconds 超时时间，0为不超时
     * @return
     */
    public static String setMap(String key, Map<String, String> value,
                                int cacheSeconds) {
        String result = null;
        Jedis jedis = null;
        boolean isBroken = false;
        try {
            jedis = getJedis();
            if (jedis.exists(key)) {
                jedis.del(key);
            }
            result = jedis.hmset(key, value);
            if (cacheSeconds != 0) {
                jedis.expire(key, cacheSeconds);
            }
            logger.debug("setMap {} = {}", key, value);
        } catch (Exception e) {
            isBroken = true;
            logger.warn("setMap {} = {}", key, value, e);
        } finally {
            release(jedis, isBroken);
        }
        return result;
    }

    /**
     * 设置Map缓存
     *
     * @param key          键
     * @param value        值
     * @param cacheSeconds 超时时间，0为不超时
     * @return
     */
    public static String setObjectMap(String key, Map<String, Object> value,
                                      int cacheSeconds) {
        String result = null;
        Jedis jedis = null;
        boolean isBroken = false;
        try {
            jedis = getJedis();
            if (jedis.exists(getBytesKey(key))) {
                jedis.del(key);
            }
            Map<byte[], byte[]> map = Maps.newHashMap();
            for (Map.Entry<String, Object> e : value.entrySet()) {
                map.put(getBytesKey(e.getKey()), toBytes(e.getValue()));
            }
            result = jedis.hmset(getBytesKey(key), (Map<byte[], byte[]>) map);
            if (cacheSeconds != 0) {
                jedis.expire(key, cacheSeconds);
            }
            logger.debug("setObjectMap {} = {}", key, value);
        } catch (Exception e) {
            isBroken = true;
            logger.warn("setObjectMap {} = {}", key, value, e);
        } finally {
            release(jedis, isBroken);
        }
        return result;
    }

    /**
     * 向Map缓存中添加值
     *
     * @param key   键
     * @param value 值
     * @return
     */
    public static String mapPut(String key, Map<String, String> value) {
        String result = null;
        Jedis jedis = null;
        boolean isBroken = false;
        try {
            jedis = getJedis();
            result = jedis.hmset(key, value);
            logger.debug("mapPut {} = {}", key, value);
        } catch (Exception e) {
            isBroken = true;
            logger.warn("mapPut {} = {}", key, value, e);
        } finally {
            release(jedis, isBroken);
        }
        return result;
    }

    /**
     * 向Map缓存中添加值
     *
     * @param key   键
     * @param value 值
     * @return
     */
    public static String mapObjectPut(String key, Map<String, Object> value) {
        String result = null;
        Jedis jedis = null;
        boolean isBroken = false;
        try {
            jedis = getJedis();
            Map<byte[], byte[]> map = Maps.newHashMap();
            for (Map.Entry<String, Object> e : value.entrySet()) {
                map.put(getBytesKey(e.getKey()), toBytes(e.getValue()));
            }
            result = jedis.hmset(getBytesKey(key), (Map<byte[], byte[]>) map);
            logger.debug("mapObjectPut {} = {}", key, value);
        } catch (Exception e) {
            isBroken = true;
            logger.warn("mapObjectPut {} = {}", key, value, e);
        } finally {
            release(jedis, isBroken);
        }
        return result;
    }

    /**
     * 移除Map缓存中的值
     *
     * @param key    键
     * @param mapKey 值
     * @return
     */
    public static long mapRemove(String key, String mapKey) {
        long result = 0;
        Jedis jedis = null;
        boolean isBroken = false;
        try {
            jedis = getJedis();
            result = jedis.hdel(key, mapKey);
            logger.debug("mapRemove {}  {}", key, mapKey);
        } catch (Exception e) {
            isBroken = true;
            logger.warn("mapRemove {}  {}", key, mapKey, e);
        } finally {
            release(jedis, isBroken);
        }
        return result;
    }

    /**
     * 移除Map缓存中的值
     *
     * @param key    键
     * @param mapKey 值
     * @return
     */
    public static long mapObjectRemove(String key, String mapKey) {
        long result = 0;
        Jedis jedis = null;
        boolean isBroken = false;
        try {
            jedis = getJedis();
            result = jedis.hdel(getBytesKey(key), getBytesKey(mapKey));
            logger.debug("mapObjectRemove {}  {}", key, mapKey);
        } catch (Exception e) {
            isBroken = true;
            logger.warn("mapObjectRemove {}  {}", key, mapKey, e);
        } finally {
            release(jedis, isBroken);
        }
        return result;
    }

    /**
     * 删除缓存
     *
     * @param key 键
     * @return
     */
    public static long del(String key) {
        long result = 0;
        Jedis jedis = null;
        boolean isBroken = false;
        try {
            jedis = getJedis();
            if (jedis.exists(key)) {
                result = jedis.del(key);
                logger.debug("del {}", key);
            } else {
                logger.debug("del {} not exists", key);
            }
        } catch (Exception e) {
            isBroken = true;
            logger.warn("del {}", key, e);
        } finally {
            release(jedis, isBroken);
        }
        return result;
    }

    /**
     * 删除缓存
     *
     * @param key 键
     * @return
     */
    public static long delObject(String key) {
        long result = 0;
        Jedis jedis = null;
        boolean isBroken = false;
        try {
            jedis = getJedis();
            if (jedis.exists(getBytesKey(key))) {
                result = jedis.del(getBytesKey(key));
                logger.debug("delObject {}", key);
            } else {
                logger.debug("delObject {} not exists", key);
            }
        } catch (Exception e) {
            isBroken = true;
            logger.warn("delObject {}", key, e);
        } finally {
            release(jedis, isBroken);
        }
        return result;
    }

    /******************************************** 以下都是带有索引的 ***********************************************/

    /**
     * 注意： 作为一个key value存在，很多开发者自然的使用set/get方式来使用Redis，实际上这并不是最优化的使用方法。
     * 尤其在未启用VM情况下，Redis全部数据需要放入内存，节约内存尤其重要。
     * 假如一个key-value单元需要最小占用512字节，即使只存一个字节也占了512字节。
     * 这时候就有一个设计模式，可以把key复用，几个key-value放入一个key中，value再作为一个set存入，
     * 这样同样512字节就会存放10-100倍的容量。 用于存储多个key-value的值，比如可以存储好多的person Object
     * 例子：>redis-cli 存储：redis 127.0.0.1:6379> hset personhash personId
     * personObject 获得：redis 127.0.0.1:6379> hget personhash personId
     * (就可以获得当前personId对应的person对象)
     *
     * @param key
     *            hashset key
     * @param field
     *            相当于personId
     * @param value
     *            person Object
     */

    /**
     * @param DBIndex
     * @param key
     * @param field
     * @param obj
     */
    public static void hsetItem(int DBIndex, String key, String field,
                                Object obj) {
        Jedis jedis = null;
        boolean isBroken = false;
        try {
            jedis = getJedis();
            jedis.connect();
            jedis.select(DBIndex);
            jedis.hset(getBytesKey(key), getBytesKey(field), toBytes(obj));
        } catch (Exception e) {
            isBroken = true;
            logger.warn("hsetItem {}", key, e);
        } finally {
            release(jedis, isBroken);
        }
    }

    /**
     * 添加Object到cache
     *
     * @param DBIndex
     * @param key
     * @param obj
     * @param seconds
     */
    public static void addItem(int DBIndex, String key, Object obj, int seconds) {
        Jedis jedis = null;
        boolean isBroken = false;
        try {
            jedis = getJedis();
            jedis.connect();
            jedis.select(DBIndex);
            if (seconds == 0) {
                jedis.set(getBytesKey(key), toBytes(obj));
            } else {
                jedis.setex(getBytesKey(key), seconds, toBytes(obj));
            }

        } catch (Exception e) {
            isBroken = true;
            e.printStackTrace();
        } finally {
            release(jedis, isBroken);
        }
    }

    /**
     * 添加Object到cache的List中
     *
     * @param dbIndex
     * @param key
     * @param obj
     */
    public void addItemToList(int dbIndex, String key, Object obj) {
        Jedis jedis = null;
        boolean isBroken = false;
        try {
            jedis = getJedis();
            jedis.select(dbIndex);
            jedis.lpushx(getBytesKey(key), toBytes(obj));
        } catch (Exception e) {
            isBroken = true;
            e.printStackTrace();
        } finally {
            release(jedis, isBroken);
        }
    }

    /**
     * 添加Map到cache
     *
     * @param dbIndex
     * @param key
     * @param map
     */
    public void addMap(int dbIndex, String key, Map<String, String> map) {
        Jedis jedis = null;
        boolean isBroken = false;
        try {
            jedis = getJedis();
            jedis.select(dbIndex);

            if (map != null && !map.isEmpty()) {
                for (String mapKey : map.keySet()) {
                    jedis.hset(key, mapKey, map.get(mapKey));
                }
            }
        } catch (Exception e) {
            isBroken = true;
            e.printStackTrace();
        } finally {
            release(jedis, isBroken);
        }
    }

    /**
     * 添加Map到cache
     *
     * @param dbIndex
     * @param key
     * @param map
     */
    public void addMap(int dbIndex, String key, Map<String, String> map,
                       int seconds) {
        Jedis jedis = null;
        boolean isBroken = false;
        try {
            jedis = getJedis();
            jedis.select(dbIndex);

            if (map != null && !map.isEmpty()) {
                for (String mapKey : map.keySet()) {
                    jedis.hset(key, mapKey, map.get(mapKey));
                }
            }
            if (seconds != 0) {
                jedis.expire(key, seconds);
            }
        } catch (Exception e) {
            isBroken = true;
            e.printStackTrace();
        } finally {
            release(jedis, isBroken);
        }
    }

    /**
     * @param key    key
     * @param member 存储的value
     * @param score  排序字段 一般为objecId
     */
    public static void addItemToSortSet(int DBIndex, String key, Object member,
                                        double score) {
        Jedis jedis = null;
        boolean isBroken = false;
        try {
            jedis = getJedis();
            jedis.connect();
            jedis.select(DBIndex);
            jedis.zadd(getBytesKey(key), score, toBytes(member));
        } catch (Exception e) {
            isBroken = true;
            e.printStackTrace();
        } finally {
            release(jedis, isBroken);
        }
    }

    /**
     * @param DBIndex
     * @param key
     * @param list
     * @param scores
     */
    public static void addListToSortSet(int DBIndex, String key,
                                        List<Object> list, List<Double> scores) {
        Jedis jedis = null;
        boolean isBroken = false;
        try {
            jedis = getJedis();
            jedis.connect();
            jedis.select(DBIndex);
            if (list != null && !list.isEmpty() && scores != null
                    && !scores.isEmpty() && list.size() == scores.size()) {
                for (int i = 0; i < list.size(); i++) {
                    jedis.zadd(getBytesKey(key), scores.get(i),
                            toBytes(list.get(i)));
                }
            }
        } catch (Exception e) {
            isBroken = true;
            e.printStackTrace();
        } finally {
            release(jedis, isBroken);
        }
    }

    /**
     * 添加List到cache
     *
     * @param dbIndex
     * @param key
     * @param list
     */
    public void addList(int dbIndex, String key, List<String> list) {
        Jedis jedis = null;
        boolean isBroken = false;
        try {
            jedis = getJedis();
            jedis.select(dbIndex);
            if (list != null && !list.isEmpty()) {
                for (String value : list) {
                    jedis.lpush(key, value);
                }
            }
        } catch (Exception e) {
            isBroken = true;
            e.printStackTrace();
        } finally {
            release(jedis, isBroken);
        }
    }

    /**
     * 添加Set到cache
     *
     * @param dbIndex
     * @param key
     * @param members
     */
    public void addSet(int dbIndex, String key, Set<String> members) {
        Jedis jedis = null;
        boolean isBroken = false;
        try {
            jedis = getJedis();
            jedis.select(dbIndex);
            if (members != null && !members.isEmpty()) {
                for (String member : members) {
                    jedis.sadd(key, member);
                }
            }
        } catch (Exception e) {
            isBroken = true;
            e.printStackTrace();
        } finally {
            release(jedis, isBroken);
        }
    }

    /**
     * 添加byte[]到cache
     *
     * @param dbIndex
     * @param key
     * @param bytes
     */
    public void addItemByte(int dbIndex, String key, byte[] bytes) {
        Jedis jedis = null;
        boolean isBroken = false;
        try {
            jedis = getJedis();
            jedis.select(dbIndex);
            if (bytes != null && bytes.length > 0) {
                jedis.set(getBytesKey(key), bytes);
            }
        } catch (Exception e) {
            isBroken = true;
            e.printStackTrace();
        } finally {
            release(jedis, isBroken);
        }
    }

    /**
     * 添加String到cache
     *
     * @param dbIndex
     * @param key
     * @param value
     */
    public void addString(int dbIndex, String key, String value) {
        Jedis jedis = null;
        boolean isBroken = false;
        try {
            jedis = getJedis();
            jedis.select(dbIndex);
            jedis.set(key, value);
        } catch (Exception e) {
            isBroken = true;
            e.printStackTrace();
        } finally {
            release(jedis, isBroken);
        }
    }

    /**
     * 删除
     *
     * @param keys
     */
    public static void del(int DBIndex, String... keys) {
        Jedis jedis = null;
        boolean isBroken = false;
        if (keys != null) {
            try {
                jedis = getJedis();
                jedis.connect();
                jedis.select(DBIndex);
                jedis.del(keys);
            } catch (Exception e) {
                isBroken = true;
                e.printStackTrace();
            } finally {
                release(jedis, isBroken);
            }
        }
    }

    /**
     * @param DBIndex
     * @param key
     */
    public static void delItem(int DBIndex, String key) {
        Jedis jedis = null;
        boolean isBroken = false;
        try {
            jedis = getJedis();
            jedis.select(DBIndex);
            jedis.del(getBytesKey(key));

        } catch (Exception e) {
            isBroken = true;
            e.printStackTrace();
        } finally {
            release(jedis, isBroken);
        }

    }

    /**
     * 删除指定key的Set中的元素itemValue
     *
     * @param dbIndex
     * @param key
     * @param itemValue
     * @return
     */
    public boolean removeSetItem(int dbIndex, String key, String itemValue) {
        Jedis jedis = null;
        boolean isBroken = false;
        boolean flag = false;
        try {
            jedis = getJedis();
            jedis.select(dbIndex);
            Long result = jedis.srem(key, itemValue);
            if (result == 1) {
                flag = true;
            }
        } catch (Exception e) {
            isBroken = true;
            logger.error(" removeSetItem failed:", e);
        } finally {
            release(jedis, isBroken);
        }

        return flag;
    }

    /**
     * @param DBIndex
     * @param key
     * @return
     */
    public static boolean exists(int DBIndex, String key) {
        Jedis jedis = null;
        boolean isBroken = false;
        boolean result = false;
        try {
            jedis = getJedis();
            jedis.select(DBIndex);
            result = jedis.exists(getBytesKey(key));
        } catch (Exception e) {
            isBroken = true;
            logger.error(" exists failed:", e);
        } finally {
            release(jedis, isBroken);

        }
        return result;
    }

    /**
     * 判断指定key的Map中的field是否存在
     *
     * @param dbIndex
     * @param key
     * @param field
     * @return
     */
    public boolean isMapFieldExists(int dbIndex, String key, String field) {
        Jedis jedis = null;
        boolean isBroken = false;
        boolean result = false;
        try {
            jedis = getJedis();
            jedis.select(dbIndex);
            result = jedis.hexists(key, field);
        } catch (Exception e) {
            isBroken = true;
            logger.error(" isMapFieldExists failed:", e);

        } finally {
            release(jedis, isBroken);
        }

        return result;
    }

    /**
     * 判断指定key的Set中的元素itemValue是否存在
     *
     * @param dbIndex
     * @param key
     * @param itemValue
     * @return
     */
    public boolean isSetItemExist(int dbIndex, String key, String itemValue) {
        Jedis jedis = null;
        boolean isBroken = false;
        boolean flag = false;
        try {
            jedis = getJedis();
            jedis.select(dbIndex);
            flag = jedis.sismember(key, itemValue);
        } catch (Exception e) {
            isBroken = true;
            logger.error(" isSetItemExist failed:", e);
        } finally {
            release(jedis, isBroken);
        }

        return flag;
    }

    /**
     * @param key
     * @param field
     * @param obj
     * @return void
     * @author sunzy
     * @date 2016年5月10日 下午5:31:39
     * @Description 设置HashMap缓存
     */
    public static void setHashMapPipe(String key, String field, Object obj) {
        try {
            Pipeline p = getPipeline();
            p.hset(getBytesKey(key), getBytesKey(field), toBytes(obj));
            sysnCurPipe++;

            commitPipe();
        } catch (Exception e) {
            logger.warn("setHashMap {} = {}", key, field, e);
        }
    }

    /**
     * @param key
     * @param field
     * @param obj
     * @return void
     * @author sunzy
     * @date 2016年5月10日 下午5:31:39
     * @Description 设置HashMap缓存
     */
    public static void setHashMapPipe(String key, String field, String s) {
        try {
            Pipeline p = getPipeline();
            p.hset(key, field, s);
            sysnCurPipe++;

            commitPipe();
        } catch (Exception e) {
            logger.warn("setHashMap {} = {}", key, field, e);
        }
    }

    /**
     * @return void
     * @author sunzy
     * @date 2016年5月10日 下午5:32:37
     * @Description pipe自动提交
     */
    public static void commitPipe() {
        if (sysnCurPipe >= sysnMaxPipe) {
            sysnCurPipe = 0;
            releasePipe();
        }
    }

    /**
     * @return void
     * @author sunzy
     * @date 2016年5月10日 下午5:23:49
     * @Description pipe提交
     */
    public static void syncPipe() {
        sysnCurPipe = 0;
        pipe.sync();
    }

    /**
     * @return Pipeline
     * @throws JedisException
     * @author sunzy
     * @date 2016年5月10日 下午5:17:57
     * @Description 获得pipe对象
     */
    private static Pipeline getPipeline() throws JedisException {
        if (null == pipe) {
            if (null == jedisPipe) {
                try {
                    jedisPipe = pool.getResource();
                    pipe = jedisPipe.pipelined();
                } catch (JedisException e) {
                    logger.error("failed:jedisPool getResource.", e);
                    if (jedisPipe != null) {
                        pool.returnBrokenResource(jedisPipe);
                    }
                }
            } else {
                pipe = jedisPipe.pipelined();
            }
        }
        return pipe;
    }

    /**
     * @param jedis
     * @param isBroken
     * @return void
     * @author sunzy
     * @date 2016年5月10日 下午5:17:50
     * @Description 销毁pipe
     */
    public static void releasePipe() {
        if (null != pipe) {
            try {
                syncPipe();
                pipe.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        if (jedisPipe != null) {
            pool.returnBrokenResource(jedisPipe);
        }

        sysnCurPipe = 0;
        pipe = null;
        jedisPipe = null;
    }

    /**
     * 获得jedis对象
     *
     * @return
     * @throws JedisException
     */
    private static Jedis getJedis() throws JedisException {
        Jedis jedis = null;
        try {
            jedis = pool.getResource();
        } catch (JedisException e) {
            logger.error("failed:jedisPool getResource.", e);
            if (jedis != null) {
                pool.returnBrokenResource(jedis);
            }
        }
        return jedis;
    }

    /**
     * jedis销毁
     *
     * @param jedis
     * @param isBroken
     */
    private static void release(Jedis jedis, boolean isBroken) {
        if (jedis != null) {
            if (isBroken) {
                pool.returnBrokenResource(jedis);
            } else {
                pool.returnResource(jedis);
            }
        }
    }

    /**
     * 获取byte[]类型Key
     *
     * @param object
     * @return
     */
    public static byte[] getBytesKey(Object object) {
        if (object instanceof String) {
            return StrUtils.getBytes((String) object);
        } else {
            return ObjectUtils.serialize(object);
        }
    }

    /**
     * Object转换byte[]类型
     *
     * @param object
     * @return
     */
    public static byte[] toBytes(Object object) {
        return ObjectUtils.serialize(object);
    }

    /**
     * byte[]型转换Object
     *
     * @param bytes
     * @return
     */
    public static Object toObject(byte[] bytes) {
        return ObjectUtils.unserialize(bytes);
    }

}
